package cn.tedu.charging.device.dao.repository.impl;

import cn.tedu.charging.device.dao.repository.StationCacheTemplateRepository;
import cn.tedu.charging.device.pojo.StationInfoWrapper;
import cn.tedu.charging.device.pojo.po.StationPO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.BoundGeoOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 位置信息和基本信息建议分开存  基本信息可以复用
 *
 * 基本信息 可以通过什么类型存 ? 更加合理
 * String
 * Hash独享 一个站 一个hash
 * Hash共享 所有站 一个hash
 *
 *
 *
 */
@Slf4j
@Repository("GEOANDGEO")
public class StationCacheTemplateGEOAndGEOImpl
    extends AbstractStationCacheTemplate
        implements StationCacheTemplateRepository {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void save(List<StationPO> stationPOS) {
        Map<StationPO,Point> stationPOMap = new HashMap<>();
        for (StationPO stationPO : stationPOS) {
            //获取经度
            BigDecimal stationLng = stationPO.getStationLng();
            //获取纬度
            BigDecimal stationLat = stationPO.getStationLat();
            //通过 经纬度 构建RedisGEO 中的点 Point
            Point point = new Point(Double.valueOf(stationLng.toEngineeringString()),
                    Double.parseDouble(stationLat.toEngineeringString()));
            stationPOMap.put(stationPO,point);
        }
        BoundGeoOperations stations = redisTemplate.boundGeoOps("stations");
        stations.add(stationPOMap);
    }

    @Override
    public List<StationInfoWrapper> search(Double longitude, Double latitude, Double distance) {

        BoundGeoOperations stations = redisTemplate.boundGeoOps("stations");
        //通过经纬度和距离构建一个圆
        Circle circle = getCircle(longitude, latitude, distance);
        //获取查询的参数
        RedisGeoCommands.GeoRadiusCommandArgs geoRadiusArgs = getGeoRadiusArgs();
        log.debug("通过RedisGEO Circle:{} 查询附近充电站",circle);
        GeoResults<RedisGeoCommands.GeoLocation<StationPO>>
                radius = stations.radius(circle,geoRadiusArgs);
        log.debug("通过RedisGEO Circle:{} 查询附近充电站:{}",circle,radius);

        List<StationInfoWrapper> result = new ArrayList<>();

        for (GeoResult<RedisGeoCommands.GeoLocation<StationPO>> geoLocationGeoResult : radius) {
            RedisGeoCommands.GeoLocation<StationPO> content =
                    geoLocationGeoResult.getContent();
            //动态的距离 用户动态的位置 和 站点固定的位置 之间的距离
            Distance resultDistance = geoLocationGeoResult.getDistance();
            log.debug("当前充电站和用户位置的距离:{}",resultDistance);
            double value = resultDistance.getValue();
            //add(point,member)
            //content.getName() 就是 add的 member 基本信息
            //content.getPoint() 就是 add 的 point 位置信息
            StationPO stationPO = content.getName();
            // StationPO stationId = content.getName();

            // String get(stationId)
            // ShareHash get("station_infos_hash_share",stationId);
            // NoShareHash get("stationId","属性名"); 一个一个获取
            // NoShareHash Map = entry(stationId) 全部获取

            //Point point = content.getPoint();
            StationInfoWrapper stationInfo = new StationInfoWrapper();
            stationInfo.setStationPO(stationPO);
            stationInfo.setDistance(value);
            result.add(stationInfo);
        }
        return result;
    }

    @Override
    public void insert(StationPO stationPO) {

    }

    @Override
    public void update(StationPO stationPO) {

    }

    @Override
    public void delete(StationPO stationPO) {

    }

    @Override
    public StationPO getStationInfoById(String stationId) {
        return null;
    }

    @Override
    public RedisTemplate getRedisTemplate() {
        return null;
    }
}
